#ifndef __IM_VALUE_ARRAY_H__
#define __IM_VALUE_ARRAY_H__

#include <im_base_types.h>
#include <im_value.h>
/**
 * @defgroup IMValueArray
 * @ingroup PrivateIMBus
 * @{
 */

/** @struct IMValueArray
 *  @brief A container object which can hold many data with arbitrary types,
 *         The data can be bool, char/uchar, int32/uint32,
 *         int64/uint64, double, pointer, string or object.
 */

IM_BEGIN_DECLS

#define IM_VALUE_ARRAY(p)             (IM_TYPE_INSTANCE_CHECK_CAST((p),IM_TYPE_VALUE_ARRAY,IMValueArray))
#define IM_CONST_VALUE_ARRAY(p)       (IM_TYPE_INSTANCE_CHECK_CAST_CONST((p),IM_TYPE_VALUE_ARRAY,IMValueArray))
#define IM_VALUE_ARRAY_CLASS(c)       (IM_TYPE_CLASS_CHECK_CAST((c),IM_TYPE_VALUE_ARRAY,IMValueArrayClass))
#define IM_IS_VALUE_ARRAY(p)          (IM_TYPE_INSTANCE_CHECK_TYPE((p),IM_TYPE_VALUE_ARRAY))
#define IM_IS_VALUE_ARRAY_CLASS(c)    (IM_TYPE_CLASS_CHECK_TYPE((c),IM_TYPE_VALUE_ARRAY))
#define IM_VALUE_ARRAY_GET_CLASS(p)   (IM_TYPE_INSTANCE_GET_CLASS_CAST((p),IM_TYPE_VALUE_ARRAY,IMValueArrayClass))

typedef struct _IMValueArray         IMValueArray;
typedef struct _IMValueArrayClass    IMValueArrayClass;


/**
 * @brief Create a new IMValueArray object.
 */
IMValueArray*   im_value_array_new              ();
/**
 * @brief Clear an IMValueArray object.
 *
 * All data in it will be freed.
 */
void            im_value_array_clear            (IMValueArray           *array);
/**
 * @brief Reserve a specific amount of space,
 *        to prevent reallocation when inserting many
 *        items.
 */
void            im_value_array_reserve          (IMValueArray           *array,
                                                 IMSize                  space);
/**
 * @brief Get number of values stored in an IMValueArray object.
 */
IMSize          im_value_array_size             (const IMValueArray     *array);
/**
 * @brief Get type of the value at specified index.
 */
IMType          im_value_array_get_value_type   (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the value in an IMValueArray object at specified index.
 *
 * The result will be stored into specified IMValue object.
 *
 * @return Type of returned value.
 */
IMType          im_value_array_get              (const IMValueArray     *array,
                                                 IMSize                  index,
                                                 IMValue                *value);
/**
 * @brief Set the value in an IMValueArray object at specified index
 *        to a new value.
 */
void            im_value_array_set              (IMValueArray           *array,
                                                 IMSize                  index,
                                                 IMValue                *value);
/**
 * @brief Prepend a value into an IMValueArray object.
 */
IMValueArray*   im_value_array_prepend          (IMValueArray           *array,
                                                 IMValue                *value);
/**
 * @brief Append a value into an IMValueArray object.
 */
IMValueArray*   im_value_array_append           (IMValueArray           *array,
                                                 IMValue                *value);
/**
 * @brief Insert a value into the specific position in an IMValueArray object.
 */
IMValueArray*   im_value_array_insert           (IMValueArray           *array,
                                                 IMSize                  index,
                                                 IMValue                *value);
/**
 * @brief Prepend an object into an IMValueArray object.
 */
IMValueArray*   im_value_array_prepend_object   (IMValueArray           *array,
                                                 IMPointer               object);
/**
 * @brief Append an object into an IMValueArray object.
 */
IMValueArray*   im_value_array_append_object    (IMValueArray           *array,
                                                 IMPointer               object);
/**
 * @brief Insert an object into the specific position in an IMValueArray object.
 */
IMValueArray*   im_value_array_insert_object    (IMValueArray           *array,
                                                 IMSize                  index,
                                                 IMPointer               object);
/**
 * @brief Remove the value at specific position in an IMValueArray object.
 */
IMValueArray*   im_value_array_remove           (IMValueArray           *array,
                                                 IMSize                  index);
/**
 * @brief Fast remove the value at specific position in an IMValueArray object.
 *
 * The order of values in the array will be changed.
 */
IMValueArray*   im_value_array_remove_fast      (IMValueArray           *array,
                                                 IMSize                  index);

/**
 * @brief Traverse all values in an IMValueArray object by calling specific
 *        function.
 *
 * func will be called with a const IMValue object containing each value.
 * The IMValue object shouldn't be changed inside func().
 */
void            im_value_array_foreach          (const IMValueArray     *array,
                                                 IMFunc                  func,
                                                 IMPointer               user_data);
/**
 * @brief Get the char value in an IMValueArray  at specified index.
 */
IMChar          im_value_array_get_char         (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the unsigned char value in an IMValueArray  at specified index.
 */
IMUChar         im_value_array_get_uchar        (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the bool value in an IMValueArray  at specified index.
 */
IMBool          im_value_array_get_bool         (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the int16 value in an IMValueArray  at specified index.
 */
IMInt16         im_value_array_get_int16        (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the unsigned int16 value in an IMValueArray  at specified index.
 */
IMUInt16        im_value_array_get_uint16       (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the int32 value in an IMValueArray  at specified index.
 */
IMInt32         im_value_array_get_int32        (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the unsigned int32 value in an IMValueArray  at specified index.
 */
IMUInt32        im_value_array_get_uint32       (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the int64 value in an IMValueArray  at specified index.
 */
IMInt64         im_value_array_get_int64        (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the unsigned int64 value in an IMValueArray  at specified index.
 */
IMUInt64        im_value_array_get_uint64       (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the double value in an IMValueArray  at specified index.
 */
IMDouble        im_value_array_get_double       (const IMValueArray     *array,
                                                 IMSize                  index);
/**
 * @brief Get the pointer in an IMValueArray  at specified index.
 */
IMPointer       im_value_array_get_pointer      (const IMValueArray     *array,
                                                 IMSize                  index);

const IMChar*   im_value_array_get_c_string     (const IMValueArray     *array,
                                                 IMSize                  index);
IMChar*         im_value_array_dup_c_string     (const IMValueArray     *array,
                                                 IMSize                  index);
IMPointer       im_value_array_get_object       (const IMValueArray     *array,
                                                 IMSize                  index);
IMPointer       im_value_array_dup_object       (const IMValueArray     *array,
                                                 IMSize                  index);

IM_END_DECLS
/** @} */

#endif
/*
vi:ts=4:nowrap:ai:expandtab
*/
